package com.lincoln.framework.hibernate;

import com.lincoln.framework.utils.ParameterChecker;
import net.sf.json.JSONObject;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 封装分页和排序查询的结果,并继承QueryParameter的所有查询请求参数.
 * 
 * @param <T> Page中的记录类型.
 */
@SuppressWarnings("unchecked")
public class Page<T> extends QueryParameter {

	private List<T> result = null;

	private long totalCount = -1;
	
	/**
	 * 查询参数 Map
	 */
	private Map<String, Object> queryMap = new JSONObject();

	public Page() {
	}

	public Page(int pageSize) {
		this.pageSize = pageSize;
	}

	public Page(int pageSize, boolean autoCount) {
		this.pageSize = pageSize;
		this.autoCount = autoCount;
	}

	/**
	 * 取得倒转的排序方向
	 */
	public String getInverseOrder() {
		if (order.endsWith(DESC))
			return ASC;
		else
			return DESC;
	}

	/**
	 * 页内的数据列表.
	 */
	public List<T> getResult() {
		return result;
	}

	public void setResult(List<T> result) {
		this.result = result;
	}

	/**
	 * 总记录数.
	 */
	public long getTotalCount() {
		return totalCount;
	}

	public void setTotalCount(long totalCount) {
		this.totalCount = totalCount;
	}

	/**
	 * 计算总页数.
	 */
	public long getTotalPages() {
		if (totalCount == -1)
			return -1;

		long count = totalCount / pageSize;
		if (totalCount % pageSize > 0) {
			count++;
		}
		return count;
	}

	/**
	 * 是否还有下一页.
	 */
	public boolean isHasNext() {
		return (pageNo + 1 <= getTotalPages());
	}

	/**
	 * 返回下页的页号,序号从1开始.
	 */
	public int getNextPage() {
		if (isHasNext())
			return pageNo + 1;
		else
			return pageNo;
	}

	/**
	 * 是否还有上一页. 
	 */
	public boolean isHasPre() {
		return (pageNo - 1 >= 1);
	}

	/**
	 * 返回上页的页号,序号从1开始.
	 */
	public int getPrePage() {
		if (isHasPre())
			return pageNo - 1;
		else
			return pageNo;
	}
	
	/**
	 * 获取当前页面中最后一条记录的位置，序号从0开始
	 * @return
	 */
	public long getLastInCurrentPage() {
		long fistInPage = this.getFirst();
		long lastInPage = fistInPage + this.getPageSize() - 1;
		return lastInPage > this.getTotalCount() - 1 ? this.getTotalCount() - 1 : lastInPage; 
	}
	
	public void addQueryParam(String key, Object value) {
		queryMap.put(key, value.toString());
	}

	
	
	public String getQueryString() {
		return queryMap.toString();
	}

	public void setQueryString(String queryString) {
		queryMap = JSONObject.fromObject(queryString);
	}
	
	public Map<String, Object> getQueryMap() {
		return queryMap;
	}
	
	public int getIntQueryValue(String key) {
		return getIntQueryValue(key, 0);
	}
	
	public int getIntQueryValue(String key, int defaultValue) {
		if (this.queryMap.containsKey(key) && queryMap.get(key)!=null) {
			try {
				return (int)this.queryMap.get(key);
			} catch (Exception e) {
				return defaultValue;
			}
		}
		return defaultValue;
	}
	
	public Object getQueryValue(String key) {
		return getQueryValue(key, null);
	}
	
	public Object getQueryValue(String key, String defaultValue) {
		if (this.queryMap.containsKey(key) && queryMap.get(key)!=null) {
			try {
				return this.queryMap.get(key);
			} catch (Exception e) {
				return defaultValue;
			}
		}
		return defaultValue;
	}
	
	public Date getDateQueryValue(String key, String dateFormat) {
		return getDateQueryValue(key, dateFormat, null);
	}
	
	public Date getDateQueryValue(String key, String dateFormat, Date defaultValue) {
		if (this.queryMap.containsKey(key) && queryMap.get(key)!=null) {
			if(queryMap.get(key) instanceof Date){
				return (Date) queryMap.get(key);
			}
			if(queryMap.get(key) instanceof String) {
				try {
					return new SimpleDateFormat(dateFormat).parse((String) this.queryMap.get(key));
				} catch (Exception e) {
					return defaultValue;
				}
			}
		}
		return defaultValue;
	}
}
